﻿Imports System.Text
Imports System.Timers
Imports TwitterAPI
Imports System.Windows
Imports VsSpeakerCompanion
Imports System.ComponentModel.Composition
Imports System.Windows.Threading
Imports VsSpeakerCompanion.UI

Namespace StartStopSessionWidget
	''' <summary>
	''' This is a non-visual widget that will send send twitter messages when a session is about to start
	''' and when a session just finished
	''' </summary>
	Friend Class Widget
		Implements IWidget
        Private Const StartSessionSettingKey = "StartSession"
        Private Const EndSessionSettingKey = "EndSession"

		' we need access to context and some services
        Private WithEvents context As Context
		Private twitterService As TwitterService
		Private uiService As IUIService

		Public Sub New(ByVal context As Context, ByVal twitterService As TwitterService, ByVal uiService As IUIService)
			Me.context = context
			Me.twitterService = twitterService
			Me.uiService = uiService
        End Sub

        Private Sub OnContextSessionStarted() Handles context.SessionStarted
            Dim sessionStartedValue = String.Concat(Me.ConferenceHashcode, Me.SessionHashcode)

            If context.SharedSettings.Get(Of String)(StartSessionSettingKey) <> sessionStartedValue Then
                If Me.uiService.ExecuteOperation(Sub() Me.twitterService.UpdateStatus(String.Format("#{0} Just starting to present {1}, follow it at #{2}", Me.ConferenceHashcode, Me.SessionName, Me.SessionHashcode))) Then
                    context.SharedSettings.Update(StartSessionSettingKey, sessionStartedValue)
                End If
            End If
        End Sub

        Private Sub OnContextSessionEnding() Handles context.SessionEnding
            Dim sessionEndedValue = String.Concat(Me.ConferenceHashcode, Me.SessionHashcode)

            If context.SharedSettings.Get(Of String)(EndSessionSettingKey) <> sessionEndedValue Then
                Dim message As String
                Dim score As Double
                Dim total As Double

                ' depending on if we can get a meaningful score
                ' we will send one of two different message formats
                If TryCalculateScore(score, total) Then
                    ' send message including calculated score
                    message = String.Format("#{0} #{1} Just finished {2} with a score of {3}/{4}", Me.ConferenceHashcode, Me.SessionHashcode, Me.SessionName, score.ToString("0.00"), total.ToString("0"))
                Else
                    ' send message without including the score
                    message = String.Format("#{0} #{1} Just finished {2}", Me.ConferenceHashcode, Me.SessionHashcode, Me.SessionName)
                End If

                If Me.uiService.ExecuteOperation(Sub() Me.twitterService.UpdateStatus(message)) Then
                    context.SharedSettings.Update(EndSessionSettingKey, sessionEndedValue)
                End If
            End If
        End Sub

		Private Function TryCalculateScore(<System.Runtime.InteropServices.Out()> ByRef score As Double, <System.Runtime.InteropServices.Out()> ByRef total As Double) As Boolean
			total = 0
			score = total

			If Me.context.ContainsProperty("coolVotes") AndAlso Me.context.ContainsProperty("notCoolVotes") Then
				Try
                    Dim coolVotes = Me.context.GetProperty(Of Integer)("coolVotes")
                    Dim notCoolVotes = Me.context.GetProperty(Of Integer)("notCoolVotes")

					score = coolVotes
					total = coolVotes + notCoolVotes

					If total > 0 Then
						ChangeToBase5(score, total)
						Return True
					End If
				Catch
					Return False
				End Try
			End If

			Return False
		End Function

		Private Sub ChangeToBase5(ByRef score As Double, ByRef total As Double)
			score = score * 5 / total
			total = 5
		End Sub

        Private ReadOnly Property ConferenceHashcode As String
            Get
                Return Me.context.Settings.Get(Of String)("conferenceHashcode")
            End Get
        End Property

        Private ReadOnly Property SessionName As String
            Get
                Return Me.context.Settings.Get(Of String)("sessionName")
            End Get
        End Property

        Private ReadOnly Property SessionHashcode As String
            Get
                Return Me.context.Settings.Get(Of String)("sessionHashcode")
            End Get
        End Property

        Public ReadOnly Property VisualElement As UIElement Implements IWidget.VisualElement
            Get
                ' as this is a non-visual widget (it will only send twitter messages and show no UI)
                ' we just return null here and this means we want to show no UI for our widget
                Return Nothing
            End Get
        End Property

        Public Sub Reset() Implements IWidget.Reset
            ' no data to reset for this widget
        End Sub
	End Class
End Namespace